package com.yibing.test.socketchannel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		LinkedList<Callable<String>> taskList = new LinkedList<Callable<String>>();
		for (int i = 0; i < 10; ++i) {
			taskList.add(new ClientTask());
		}
		ExecutorCompletionService<String> pool = new ExecutorCompletionService<String>(Executors.newFixedThreadPool(3));
		for (Callable<String> t : taskList)
			pool.submit(t);
		
		for (int i = 0; i < taskList.size(); ++i) {
			try {
				System.out.println(pool.take().get());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//pool.shutdown();
	}
	
}

class ClientTask implements Callable<String> {

	@Override
	public String call() throws Exception {
		StringBuilder result = null;
		try {
			InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 11009);
			SocketChannel sc = SocketChannel.open(addr);
			
			ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
			String msg = new String("Hello from client!");
			for (int i = 0; i < msg.length(); ++i) {
				sendBuffer.putChar(msg.charAt(i));
			}
			sendBuffer.flip();
			int bytesWritten = sc.write(sendBuffer);
			
			ByteBuffer recvBuffer = ByteBuffer.allocate(1024);
			int bytesRead = sc.read(recvBuffer);
			result = new StringBuilder("" + Thread.currentThread() + "Send " + bytesWritten 
					+ "; Receive " + bytesRead + " bytes from server: ");
			recvBuffer.flip();
			CharBuffer cb = recvBuffer.asCharBuffer();
			for (int i = 0; i < cb.length(); ++i) {
				result.append(cb.charAt(i));
			}
			
			sendBuffer = ByteBuffer.allocate(1024);
			for (int i = 0; i < msg.length(); ++i) {
				sendBuffer.putChar(msg.charAt(i));
			}
			sendBuffer.flip();
			bytesWritten = sc.write(sendBuffer);
			
			recvBuffer = ByteBuffer.allocate(1024);
			bytesRead = sc.read(recvBuffer);
			result.append("\n" + Thread.currentThread() + "Send " + bytesWritten 
					+ "; Receive " + bytesRead + " bytes from server: ");
			recvBuffer.flip();
			cb = recvBuffer.asCharBuffer();
			for (int i = 0; i < cb.length(); ++i) {
				result.append(cb.charAt(i));
			}
			
			sc.close();			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return result.toString();
	}
	
}